﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Windows.Forms;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Input = Microsoft.Xna.Framework.Input; // to provide shorthand to clear up ambiguities

namespace J2i.Net.XnaXboxController
{
    class gamepad
    {
       GamePadState gamePadState;
       GamePadState previousState;
       PlayerIndex playerIndex;
       udpSocket myUdpSocket;

       public Boolean buttonAChecked;
       public Boolean buttonBChecked;
       public Boolean buttonXChecked;
       public Boolean buttonYChecked;
       public Boolean buttonUpChecked;
       public Boolean buttonDownChecked;
       public Boolean buttonLeftChecked;
       public Boolean buttonRightChecked;
       public Boolean lblNotConnected;
       float leftMotor = 0;
       float rightMotor = 0;

       Form myform;
       int id;

       int team;
       int vibrationCountdown = 0;
       int shootCountdown = 0;
       public int leftTriggerPosition;
       public int rightTriggerPosition;

       public gamepad(Form _myform, PlayerIndex _playerIndex, udpSocket _myUdpSocket) 
       {
           myUdpSocket = _myUdpSocket;
           myform = _myform;
           playerIndex = _playerIndex;
       }

       public void setTeam( int value)
       {
           team = value;
       }

       public void setVibration(string type)
       {
           switch (type) 
           { 
               case "test":
                   this.leftMotor = this.rightMotor = 0.9f;
                   this.vibrationCountdown = 5;
                   break;
               case "die":
                   this.leftMotor = this.rightMotor = 0.9f;
                   this.vibrationCountdown = 30;
                   break;
               case "shooting":
                   this.leftMotor = this.rightMotor = 0.75f;
                   this.vibrationCountdown = 2;
                   break;
               case "stop":
                   this.leftMotor = this.rightMotor = 0.0f;
                   break;
               default:
                   break;
           }
           GamePad.SetVibration(this.playerIndex, this.leftMotor, this.rightMotor);
           
        }

       public void setPlayer(PlayerIndex _playerIndex)
       {
           this.playerIndex  = _playerIndex;
       }

       public void updateData()
       {
           //Get the new gamepad state and save the old state.
           this.previousState = this.gamePadState;
           this.gamePadState = GamePad.GetState(this.playerIndex);

           //If the controller is not connected, let the user know
           lblNotConnected = !this.gamePadState.IsConnected;
           //I personally prefer to only update the buttons if their state has been changed. 
           if (!this.gamePadState.Buttons.Equals(this.previousState.Buttons))
           {
               this.buttonAChecked = (this.gamePadState.Buttons.A == Input.ButtonState.Pressed);
               this.buttonBChecked = (this.gamePadState.Buttons.B == Input.ButtonState.Pressed);
               this.buttonXChecked = (this.gamePadState.Buttons.X == Input.ButtonState.Pressed);
               this.buttonYChecked = (this.gamePadState.Buttons.Y == Input.ButtonState.Pressed);
           }
           if (!this.gamePadState.DPad.Equals(this.previousState.DPad))
           {
               this.buttonUpChecked = (this.gamePadState.DPad.Up == Input.ButtonState.Pressed);
               if(this.buttonUpChecked) myUdpSocket.sendMessage(1, team,this.id, 0);
               this.buttonDownChecked = (this.gamePadState.DPad.Down == Input.ButtonState.Pressed);
               if (this.buttonDownChecked) myUdpSocket.sendMessage(2,  team,this.id, 0);
               this.buttonLeftChecked = (this.gamePadState.DPad.Left == Input.ButtonState.Pressed);
               if (this.buttonLeftChecked) myUdpSocket.sendMessage(3, team,this.id,0);
               this.buttonRightChecked = (this.gamePadState.DPad.Right == Input.ButtonState.Pressed);
               if (this.buttonRightChecked) myUdpSocket.sendMessage(4, team,this.id,0);
           }

           //Update the position of the thumb sticks
           //since the thumbsticks can return a number between -1.0 and +1.0 I had to shift (add 1.0)
           //and scale (mutiplication by 100/2, or 50) to get the numbers to be in the range of 0-100
           //for the progress bar
           /*
           this.x1Position.Value = (int)((this.gamePadState.ThumbSticks.Left.X + 1.0f) * 100.0f / 2.0f);
           this.y1Position.Value = (int)((this.gamePadState.ThumbSticks.Left.Y + 1.0f) * 100.0f / 2.0f);
           this.x2position.Value = (int)((this.gamePadState.ThumbSticks.Right.X + 1.0f) * 100.0f / 2.0f);
           this.y2position.Value = (int)((this.gamePadState.ThumbSticks.Right.Y + 1.0f) * 100.0f / 2.0f);
           */
           //The triggers return a value between 0.0 and 1.0.  I only needed to scale these values for
           //the progress bar
           this.leftTriggerPosition = (int)((this.gamePadState.Triggers.Left * 100));
           this.rightTriggerPosition = (int)(this.gamePadState.Triggers.Right * 100);
           // send message after release buttons
           if (this.previousState.Triggers.Right == 1 && this.previousState.Triggers.Left == 1 && !(leftTriggerPosition == 100 && this.rightTriggerPosition == 100))
           {
               if (this.shootCountdown <= 0) { myUdpSocket.sendMessage(6, team, this.id, 0); }
               else
               {
                   myUdpSocket.sendMessage(7, team, this.id, 0);
               }
           }
           // reset countdown
           if (this.previousState.Triggers.Right != 1 && this.previousState.Triggers.Left != 1) 
           {
               this.shootCountdown = 20;
           }
           if( leftTriggerPosition == 100 && this.rightTriggerPosition == 100 )
           {
               if (this.vibrationCountdown > 0)
               {
                   --this.shootCountdown;
               }
               setVibration("shooting");
               myUdpSocket.sendMessage(5, team, this.id, this.shootCountdown);
           }

           this.CheckVibrationTimeout();
       }

       private void CheckVibrationTimeout()
       {
           if (this.vibrationCountdown > 0)
           {
               --this.vibrationCountdown;
               if (this.vibrationCountdown == 0)
               {
                   GamePad.SetVibration(this.playerIndex, 0, 0);
               }
           }
       }

    }
}
